package vip.liux.backend.adapter.webflux;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.stereotype.Component;
import vip.liux.contracts.infrastructure.threads.DynamicThreadPoolExecutor;

import java.util.HashMap;
import java.util.Map;

@Component
@Endpoint(id = "thread-pool")
public class ThreadPoolEndpoint {

    private final DynamicThreadPoolExecutor executor;

    public ThreadPoolEndpoint(DynamicThreadPoolExecutor executor) {
        this.executor = executor;
    }

    @ReadOperation
    public Map<String, Object> status() {
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("corePoolSize", executor.getCorePoolSize());
        metrics.put("maxPoolSize", executor.getMaxPoolSize());
        metrics.put("keepAliveSeconds", executor.getKeepAliveSeconds());
        metrics.put("queueCapacity", executor.getQueueCapacity());
        metrics.put("activeCount", executor.getActiveCount());
        metrics.put("poolSize", executor.getPoolSize());
        metrics.put("completedTaskCount", executor.getCompletedTaskCount());
        metrics.put("queueSize", executor.getQueueSize());
        metrics.put("loadFactor", executor.getLoadFactor());
        return metrics;
    }

    @WriteOperation
    public String adjust(
            Integer corePoolSize,
            Integer maxPoolSize,
            Long keepAliveSeconds,
            Integer queueCapacity) {

        StringBuilder result = new StringBuilder("Adjusted parameters:");

        if (corePoolSize != null) {
            executor.setCorePoolSize(corePoolSize);
            result.append(" corePoolSize=").append(corePoolSize);
        }
        if (maxPoolSize != null) {
            executor.setMaxPoolSize(maxPoolSize);
            result.append(" maxPoolSize=").append(maxPoolSize);
        }
        if (keepAliveSeconds != null) {
            executor.setKeepAliveSeconds(keepAliveSeconds);
            result.append(" keepAliveSeconds=").append(keepAliveSeconds);
        }
        if (queueCapacity != null) {
            executor.setQueueCapacity(queueCapacity);
            result.append(" queueCapacity=").append(queueCapacity);
        }

        return result.toString();
    }
}